package top.cardone.web.support;

import com.google.gson.Gson;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import top.cardone.context.ApplicationContextHolder;
import top.cardone.core.CodeException;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Map;

/**
 * Created by yht on 16-3-23.
 */
@Log4j2
public class WebSupport {
    /**
     * 获取对象
     *
     * @param cls
     * @param request
     * @param <T>
     * @return
     */
    public <T> T getObject(Class<T> cls, HttpServletRequest request) {
        if (StringUtils.startsWith(request.getContentType(), org.springframework.http.MediaType.APPLICATION_JSON_VALUE)) {
            return this.getObjectByJson(cls, request);
        }

        return this.getObjectByParameter(cls, request);
    }

    /**
     * 获取对象
     *
     * @param cls
     * @param request
     * @param <T>
     * @return
     */
    public <T> T getObjectByJson(Class<T> cls, HttpServletRequest request) {
        String jsonString;

        try (java.io.InputStream is = request.getInputStream()) {
            jsonString = IOUtils.toString(is, request.getCharacterEncoding());
        } catch (IOException e) {
            throw new CodeException("000012", new String[]{e.getMessage()}, e);
        }

        if (StringUtils.isBlank(jsonString)) {
            jsonString = "{}";
        }

        //输入参数为 map 时，优化获取 request 参数后，再合并
        if (Map.class.equals(cls)) {
            Map<String, Object> parameterMap = org.springframework.web.util.WebUtils.getParametersStartingWith(request, null);

            Map<String, Object> jsonMap = ApplicationContextHolder.getBean(Gson.class).fromJson(jsonString, Map.class);

            if (MapUtils.isNotEmpty(jsonMap)) {
                parameterMap.putAll(jsonMap);
            }

            return (T) parameterMap;
        }

        if (java.lang.String.class.equals(cls) || java.lang.Object.class.equals(cls)) {
            return (T) jsonString;
        }

        return ApplicationContextHolder.getBean(Gson.class).fromJson(jsonString, cls);
    }

    /**
     * 获取对象
     *
     * @param cls
     * @param request
     * @param <T>
     * @return
     */
    public <T> T getObjectByParameter(Class<T> cls, HttpServletRequest request) {
        Map<String, Object> parameterMap = org.springframework.web.util.WebUtils.getParametersStartingWith(request, null);

        if (java.util.Map.class.equals(cls) || java.lang.Object.class.equals(cls)) {
            return (T) parameterMap;
        }

        String jsonString = ApplicationContextHolder.getBean(Gson.class).toJson(parameterMap);

        if (java.lang.String.class.equals(cls) || java.lang.Object.class.equals(cls)) {
            return (T) jsonString;
        }

        return ApplicationContextHolder.getBean(Gson.class).fromJson(jsonString, cls);
    }
}
